use actix_web::{delete, get, post, web, App, HttpServer, Result};
use serde::Deserialize;

/// http://localhost:8080/users/12/silwings
#[get("/users/{user_id}/{friend}")]
async fn index(path: web::Path<(u32, String)>) -> Result<String> {
    let (user_id, friend) = path.into_inner();
    Ok(format!("Welcome {}, user_id {}!", friend, user_id))
}

#[derive(Deserialize)]
struct Info {
    user_id: u32,
    friend: String,
}

/// http://localhost:8080/users2/12/silwings
#[get("/users2/{user_id}/{friend}")]
async fn index_2(path: web::Path<Info>) -> Result<String> {
    let info = path.into_inner();
    Ok(format!(
        "Welcome {}, user_id {}!",
        info.friend, info.user_id
    ))
}

#[derive(Deserialize)]
struct User {
    username: String,
}

/// 如果请求信息能成功反序列化为“Info”，则调用此处理程序
/// http://localhost:8080/?username=www
#[get("/")]
async fn index_3(info: web::Query<User>) -> String {
    format!("Welcome {}", info.username)
}

#[derive(Deserialize)]
struct Teacher {
    username: String,
    age: u32,
}

#[post("/submit")]
async fn submit(info: web::Json<Teacher>) -> String {
    format!("Welcome {}:{}!", info.username, info.age)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(index).service(index_2).service(index_3).service(submit))
        .bind(("127.0.0.1", 8080))?
        .run()
        .await
}
